﻿#region Using

using SAPbouiCOM;
using SapFramework.Interface.Controls.Items.Base;
using SapFramework.Interface.Events;

using Form = SapFramework.Interface.Controls.Forms.Base.Form;
using Item = SapFramework.Interface.Controls.Items.Base.Item;

#endregion

namespace SapFramework.Interface.Controls.Items.Specific
{
    /// <summary>
    /// Realiza o encapsulamento de um objeto do tipo <see cref="SAPbouiCOM.Grid"/> da UI API do SAP Business One
    /// </summary>
    public sealed class Grid : Item, SAPbouiCOM.Grid
    {
        #region Eventos

        /// <summary>
        /// Ocorre depois que o item recebe o foco.
        /// </summary>
        /// <remarks>
        /// Disponivel para Colunas
        /// </remarks>
        [Event( BoEventTypes.et_GOT_FOCUS )]
        public event EventVoidItem OnGotFocus;

        /// <summary>
        /// Ocorre depois que o item perde o foco.
        /// </summary>
        /// <remarks>
        /// Disponivel para Colunas
        /// </remarks>
        [Event( BoEventTypes.et_LOST_FOCUS )]
        public event EventVoidItem OnLostFocus;

        /// <summary>
        /// Eventos que ocorre quando um item perdeu o fóco e a validação é obrigatória para ele, mas ainda não ocorreu.
        /// </summary>
        /// <remarks>
        /// Disponivel para Colunas
        /// </remarks>
        [Event( BoEventTypes.et_VALIDATE )]
        public event EventBoolItem OnBeforeValidate;

        /// <summary>
        /// Eventos que ocorre quando um item perdeu o fóco e a validação é obrigatória para ele, e esta validação já ocorreu.
        /// </summary>
        /// <remarks>
        /// Disponivel para Colunas
        /// </remarks>
        [Event( BoEventTypes.et_VALIDATE )]
        public event EventVoidItem OnAfterValidate;

        /// <summary>
        /// Evento disparado quando o botão do mouse foi liberado em cima de um item, ou seja, quando o botão do mouse está em cima, mas nenhuma ação foi tomada ainda.
        /// </summary>
        /// <remarks>
        /// Disponivel para Colunas
        /// </remarks>
        [Event( BoEventTypes.et_ITEM_PRESSED )]
        public event EventBoolItem OnBeforeItemPressed;

        /// <summary>
        /// Evento disparado quando o botão do mouse foi liberado em cima de um item, ou seja, quando o botão do mouse está em cima, e qualquer ação do SBO já foi realizada.
        /// </summary>
        /// <remarks>
        /// Disponivel para Colunas
        /// </remarks>
        [Event( BoEventTypes.et_ITEM_PRESSED )]
        public event EventVoidItem OnAfterItemPressed;

        /// <summary>
        /// Ocorre quando um item na ComboBox foi selecionado, porém nenhuma ação foi tomada ainda.
        /// </summary>
        /// <remarks>
        /// Disponivel para Colunas
        /// </remarks>
        [Event( BoEventTypes.et_COMBO_SELECT )]
        public event EventBoolItem OnBeforeComboSelect;

        /// <summary>
        /// Ocorre quando um item na ComboBox foi selecionado, e qualquer ação do SBO já foi executada.
        /// </summary>
        /// <remarks>
        /// Disponivel para Colunas
        /// </remarks>
        [Event( BoEventTypes.et_COMBO_SELECT )]
        public event EventVoidItem OnAfterComboSelect;

        /// <summary>
        /// Evento que ocorre quando um botão de ChooseFromList foi clicado, mas ela ainda não foi invocada.
        /// </summary>
        /// <remarks>
        /// Disponivel para Colunas e Linhas
        /// </remarks>
        [Event( BoEventTypes.et_CHOOSE_FROM_LIST )]
        public event EventBoolChooseFromList OnBeforeChooseFromList;

        /// <summary>
        /// Evento que ocorre quando um botão de ChooseFromList foi clicado, e ela já está a mostra.
        /// </summary>
        /// <remarks>
        /// Disponivel para Colunas e Linhas
        /// </remarks>
        [Event( BoEventTypes.et_CHOOSE_FROM_LIST )]
        public event EventVoidChooseFromList OnAfterChooseFromList;

        /// <summary>
        /// Ocorre quando uma tecla for pressionado sobre a EditText, porém nenhuma ação foi tomada ainda.
        /// </summary>
        [Event( BoEventTypes.et_KEY_DOWN )]
        public event EventBoolItem OnBeforeKeyDown;

        /// <summary>
        /// Ocorre quando uma tecla for pressionado sobre a EditText, e qualquer ação do SBO já foi executada.
        /// </summary>
        [Event( BoEventTypes.et_KEY_DOWN )]
        public event EventVoidItem OnAfterKeyDown;

        /// <summary>
        /// Disparado antes da exibição do menu que ocorre quando um clique com o botão direito do mouse é feito sobre um item.
        /// </summary>
        /// <remarks>
        /// Disponivel para Colunas
        /// </remarks>
        [Event( BoEventTypes.et_RIGHT_CLICK )]
        public event EventBoolContextMenu OnBeforeRightClick;

        /// <summary>
        /// Disparado após a exibição do menu que ocorre quando um clique com o botão direito do mouse é feito sobre um item.
        /// </summary>
        /// <remarks>
        /// Disponivel para Colunas
        /// </remarks>
        [Event( BoEventTypes.et_RIGHT_CLICK )]
        public event EventVoidContextMenu OnAfterRightClick;

        #endregion

        /// <summary>
        /// Guarda uma referencia para a parte específica do item
        /// </summary>
        private readonly SAPbouiCOM.Grid mGrid;

        /// <summary>
        /// Construtor
        /// </summary>
        /// <param name="aForm">O formulário ao qual o item pertence</param>
        /// <param name="aItemUniqueId">Id único do Item do Form do SAP Business One</param>
        /// <param name="aItemType">O tipo do Item para o SAP Business One</param>
        public Grid( Form aForm, string aItemUniqueId, BoFormItemTypes aItemType ) : base( aForm, aItemUniqueId, aItemType )
        {
            mGrid = mItem.Specific as SAPbouiCOM.Grid;
        }

        #region Implementation of IGrid

        /// <summary>
        /// Alonga as colunas até o tamanho limite da Grid, redimensionando delas.
        /// </summary>
        /// <remarks>
        /// O comprimento de uma Grid pode ser maior do que o comprimento total de todas as colunas, criando um espaço entre a ultima coluna e o final da Grid.
        /// 
        /// O SAP Business One supera este problema redimensionando todas as colunas sempre que a grid é redesenhada. 
        /// Isto pode acontecer inesperadamente quando você trabalha com uma Grid.
        /// 
        /// Sendo assim, é recomendado invocar o método <see cref="AutoResizeColumns"/> sempre que você terminar de criar uma grid, 
        /// assim garantindo que as colunas estejam sempre alongadas até o tamanho total da Grid.
        /// </remarks>
        public void AutoResizeColumns()
        {
            mGrid.AutoResizeColumns();
        }

        /// <summary>
        /// Retorna a linha da <see cref="DataTable"/> para uma linha específica da Grid.
        /// </summary>
        /// <param name="aRowIndex">O índice da linha da Grid para o qual se deseja recuperar a linha na DataTable</param>
        /// <returns>O índice da linha para a <see cref="DataTable"/> correspondente ou -1 se ocorrer um erro.</returns>
        public int GetDataTableRowIndex( int aRowIndex )
        {
            return mGrid.GetDataTableRowIndex( aRowIndex );
        }

        /// <summary>
        /// O número de colunas agrupadas em conjunto, partindo da coluna mais a esquerda. 
        /// 
        /// Se você especificar 2 para esta propriedade, todas as linhas serão agrupadas pelos valores da primeira colunas,
        /// e todas as linhas dentro de cada grupo serão agrupadas pelo valor da segunda coluna.
        ///  </summary>
        /// <remarks>
        /// As colunas que estão agrupadas estão ordenadas, assim como a coluna seguinte.
        /// 
        /// Por exemplo, se setado para 2, as primeiras três colunas serão ordenadas.
        /// </remarks>
        public int CollapseLevel
        {
            get { return mGrid.CollapseLevel; }
            set { mGrid.CollapseLevel = value; }
        }

        /// <summary>
        /// As linhas da Grid. O objeto GridRows gerencia ações nas linhas da grid, tais como o recolhimento e a expansão de linhas.
        /// </summary>
        public GridRows Rows
        {
            get { return mGrid.Rows; }
        }

        /// <summary>
        /// Indica como as linhas podem ser selecionadas.
        /// </summary>
        public BoMatrixSelect SelectionMode
        {
            get { return mGrid.SelectionMode; }
            set { mGrid.SelectionMode = value; }
        }

        /// <summary>
        /// A <see cref="DataTable"/> ligada a Grid.
        /// </summary>
        /// <remarks>
        /// Por padrão, a Grid não é ligada a uma DataTable. Para liga-la, você deve explicitamente especificar uma <see cref="DataTable"/>.
        /// </remarks>
        public DataTable DataTable
        {
            get { return mGrid.DataTable; }
            set { mGrid.DataTable = value; }
        }

        /// <summary>
        /// Os cabeçalhos das colunas da Grid, que presentam o cabeçalho vertical de uma grid, 
        /// que parecem com botões mostrando o número das linhas.
        /// </summary>
        public RowHeaders RowHeaders
        {
            get { return mGrid.RowHeaders; }
        }

        /// <summary>
        /// Colunas da Grid.
        /// </summary>
        public GridColumns Columns
        {
            get { return mGrid.Columns; }
        }

        /// <summary>
        /// Recupera as coordenadas da célula que está em fóco.
        /// </summary>
        /// <returns></returns>
        public CellPosition GetCellFocus()
        {
            return mGrid.GetCellFocus();
        }

        /// <summary>
        /// Seta o fóco na célula que está na aRowNum e aColNum especificadas
        /// </summary>
        /// <param name="aRowNum">Número da linha, começando de zero.</param>
        /// <param name="aColNum">Número da coluna, começando de zero.</param>
        public void SetCellFocus( int aRowNum, int aColNum )
        {
            mGrid.SetCellFocus( aRowNum, aColNum );
        }

        /// <summary>
        /// Propriedades em comum para as células da Grid.
        /// </summary>
        /// <remarks>
        /// Permise deixar colunas e linhas editaveis ou não, ou até alterar suas cores.
        /// </remarks>
        public CommonSetting CommonSetting
        {
            get { return mGrid.CommonSetting; }
        }

        #endregion
    }
}